package org.cytoscape.myapp.cytoscape_app_v1.internal.metrics.measure;

import java.util.ArrayList;
import java.util.List;

import org.cytoscape.myapp.cytoscape_app_v1.internal.metrics.domain.User;
import org.cytoscape.myapp.cytoscape_app_v1.internal.metrics.domain.UserPositionMapping;



public class SocialSimilarity {

	private UserPositionMapping mapping;
	
	public SocialSimilarity(UserPositionMapping mapping) {
		this.mapping=mapping;
	}

	/**
	 * Return the Social Similarity Matrix
	 * @return double[][]
	 */
	public double[][] getSSMatrix() { 
		double[][] ss=new double[this.mapping.getUsers().size()][this.mapping.getUsers().size()];
		double alpha=0.2;
		double beta=0.8;
		List<String> lines=new ArrayList<String>();
		for (int i=0;i<this.mapping.getUsers().size();i++) {
			for (int j=i+1;j<this.mapping.getUsers().size();j++) {
				if(i!=j){
					User user1=this.mapping.getUsers().get(this.mapping.getUserIdByPosition(i));
					User user2=this.mapping.getUsers().get(this.mapping.getUserIdByPosition(j));
					double sst=getSsJaccard(user1,user2);
					double sa=getSaOverlap(user1,user2);
					double socialSimilarity=alpha*sst+beta*sa;
					if(socialSimilarity!=0.0){
						ss[i][j]=socialSimilarity;
						lines.add(user1.getId()+","+user2.getId()+","+socialSimilarity);
					}
				}
			}
		}
		return ss;
	}

	private static double getSsJaccard(User user1, User user2) {
		double intersection=0.0;
		List<String> friends1=user1.getFriends();
		List<String> friends2=user2.getFriends();
		if(friends1.size()!=0 && friends2.size()!=0){
			for (String fiend1 : friends1) {
				if(friends2.contains(fiend1))
					intersection++;
			}
		}
		double union=friends1.size()+friends2.size();
		if(intersection!=0 && union!=0){
			return intersection/union;
		}
		else 
			return 0;
	}

	private static double getSaOverlap(User user1, User user2) {
		double sactivities=getSActivities(user1,user2);
		double stastes=getSTastes(user1,user2);
		double saOverlap=(sactivities+stastes)/2;
		return saOverlap;
	}

	private static double getSTastes(User user1, User user2) {
		double intersection=getLikesIntersection(user1.getLikes(),user2.getLikes());
		intersection+=getIntersection(user1.getBooks(),user2.getBooks(),user1.getLikes());
		intersection+=getIntersection(user1.getMusic(),user2.getMusic(),user1.getLikes());
		intersection+=getIntersection(user1.getTeams(),user2.getTeams(),user1.getLikes());
		intersection+=getIntersection(user1.getAthletes(),user2.getAthletes(),user1.getLikes());
		intersection+=getIntersection(user1.getMovies(),user2.getMovies(),user1.getLikes());
		intersection+=getIntersection(user1.getTelevision(),user2.getTelevision(),user1.getLikes());
		double sum1=user1.getLikes().size()+user1.getBooks().size()+user1.getMusic().size()+user1.getTeams().size()+user1.getAthletes().size()+user1.getMovies().size()+user1.getTelevision().size();
		double sum2=user2.getLikes().size()+user2.getBooks().size()+user2.getMusic().size()+user2.getTeams().size()+user2.getAthletes().size()+user2.getMovies().size()+user2.getTelevision().size();
		double den=0.0;
		if(sum1<sum2)
			den=sum1;
		else
			den=sum2;
		if(den!=0 && intersection!=0){
			double saoverlap=intersection/den;
			return saoverlap;
		}
		else 
			return 0;
	}

	private static double getLikesIntersection(List<String> likes1,List<String> likes2) {
		double intersection = 0.0;
		if(likes1.size()!=0 && likes2.size()!=0){
			for (String string : likes1) {
				if(likes2.contains(string))
					intersection++;
			}
		}
		return intersection;
	}

	private static double getIntersection(List<String> list1, List<String> list2, List<String> likes1) {
		double intersection = 0.0;
		if(list1.size()!=0 && list2.size()!=0){
			for (String string : list1) {
				if(!likes1.contains(string))
					if(list2.contains(string))
						intersection++;
			}
		}
		return intersection;
	}

	private static double getSActivities(User user1, User user2) {
		List<String> groups1=user1.getGroups();
		List<String> groups2=user2.getGroups();
		List<String> games1=user1.getGames();
		List<String> games2=user2.getGames();

		double intersection=0.0;
		for (String group : groups1) {
			if(groups2.contains(group))
				intersection++;
		}
		for (String game : games1) {
			if(games2.contains(game))
				intersection++;
		}
		double sum1=groups1.size()+games1.size();
		double sum2=groups2.size()+games2.size();
		double den=0.0;
		if(sum1<sum2)
			den=sum1;
		else
			den=sum2;

		if(den!=0 && intersection!=0){
			double saoverlap=intersection/den;
			return saoverlap;
		}
		else
			return 0;
	}
}
